package com.ych.modules.common.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.ych.SDK.alibaba.alipaySDK.AlipayUtil;
import com.ych.SDK.alibaba.alipaySDK.config.AlipayConfig;
import com.ych.SDK.alibaba.alipaySDK.entity.AlipayQueryOrderInfo_Request;
import com.ych.SDK.alibaba.alipaySDK.entity.AlipayRefundEntity;
import com.ych.modules.base.dbEntity.TUserAccountRechargeOrderEntity;
import com.ych.modules.base.service.ITUserAccountRechargeOrderService;
import com.ych.modules.base.service.ITUserAccountService;
import com.ych.modules.common.entity.query.QueryAccountRechargeOrderEntity;
import com.ych.modules.common.service.UserAccountRechargeOrderService;
import com.ych.rabbitmq.exchange.DemoExchange;
import com.ych.rabbitmq.exchange.UserRechargeOrderExchange;
import com.ych.redis.RedisLockUtil;
import com.ych.utils.DateUtils;
import com.ych.utils.UUID;
import com.ych.utils.beanToMap.BeanMapUtil;
import com.ych.utils.mysqlPageUtil.Query;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 * Author: Usopp.tsui
 * Date: 2020/12/31
 * Time: 15:26
 * Description:
 */
@Service("UserAccountRechargeOrderService")
public class UserAccountRechargeOrderServiceImpl implements UserAccountRechargeOrderService {
    @Autowired
    private ITUserAccountRechargeOrderService itUserAccountRechargeOrderService;
    @Autowired
    private RabbitTemplate                    rabbitTemplate;
    @Autowired
    private ITUserAccountService              itUserAccountService;

    @Override
    public TUserAccountRechargeOrderEntity getAccountRechargeOrder(String orderId) {
        return itUserAccountRechargeOrderService.selectById(orderId);
    }

    @Override
    public Page<TUserAccountRechargeOrderEntity> listAccountRechargeOrder(QueryAccountRechargeOrderEntity entity) {
        Wrapper<TUserAccountRechargeOrderEntity> wrapper = new EntityWrapper<TUserAccountRechargeOrderEntity>()
                .where("1=1")
                .eq(StringUtils.isNotBlank(entity.getRechargeId()), "recharge_id", entity.getRechargeId())
                .eq(StringUtils.isNotBlank(entity.getRechargeChannel()), "recharge_channel", entity.getRechargeChannel())
                .eq(StringUtils.isNotBlank(entity.getRechargeStatus()), "recharge_status", entity.getRechargeStatus())
                .eq(StringUtils.isNotBlank(entity.getUserId()), "user_id", entity.getUserId())
                .orderBy("create_time DESC");
        Page<TUserAccountRechargeOrderEntity> page = itUserAccountRechargeOrderService.selectPage(new Query<TUserAccountRechargeOrderEntity>(BeanMapUtil.toPageQuery(entity)).getPage(), wrapper);
        return page;
    }

    @Override
    public String createOrder(TUserAccountRechargeOrderEntity entity) {
        if (null == entity.getCashAmount()
                || StringUtils.isBlank(entity.getUserId())
                || StringUtils.isBlank(entity.getRechargeChannel())) {
            throw new RuntimeException("必传参数存在null值！");
        }
        entity.setRechargeId(UUID.randomUUID());
        entity.setCreateTime(new Date());
        entity.setRechargeStatus("10003001");
        Integer vip = 0;//没有说这个vip规则，暂时所有用户充值都是0
        entity.setVip(vip);
        BigDecimal goldCoinAmount = entity.getCashAmount().multiply(new BigDecimal("10"));//支付金额*10=金币数量
        entity.setGoldCoinAmount(goldCoinAmount);
        String result = "";
        switch (entity.getRechargeChannel()) {
            case "10002002"://支付宝支付
                result = AlipayUtil.createOrder(entity);
                entity.setCollectionAccount(AlipayConfig.collection_account);//收款账户
                break;
            case "10005004":
            default:
                throw new RuntimeException("暂时不支持该付款方式！");
        }
        //添加充值交易记录
        itUserAccountRechargeOrderService.insert(entity);
        //拥有orderId 则不在这里进行mq控制
        try {
            //发送延时消息，延时8分钟处理订单
            rabbitTemplate.convertAndSend(UserRechargeOrderExchange.EXCHANGE_NAME, UserRechargeOrderExchange.QUEUE_NAME, entity.getRechargeId(),
                    message -> {
                        message.getMessageProperties().setHeader("x-delay", 8 * 60 * 1000);//转为毫秒
                        return message;
                    });
        } catch (Exception e) {

        }
        try {
            //发送延时消息，延时12分钟处理订单
            rabbitTemplate.convertAndSend(UserRechargeOrderExchange.EXCHANGE_NAME, UserRechargeOrderExchange.QUEUE_NAME, entity.getRechargeId(),
                    message -> {
                        message.getMessageProperties().setHeader("x-delay", 12 * 60 * 1000);//转为毫秒
                        return message;
                    });
        } catch (Exception e) {

        }
        return result;
    }

    @Override
    public void dealOrderCallback(AlipayQueryOrderInfo_Request orderEntity) {
        String lock = "alipay:" + orderEntity.getOut_trade_no();
        String lockId = UUID.randomUUID();
        try {
            if (RedisLockUtil.tryLock(lock, lockId, 60 * 15)) { //分布式上锁15分钟
                String response;
                //1.查询订单信息
                TUserAccountRechargeOrderEntity dbOrder = itUserAccountRechargeOrderService.selectById(orderEntity.getOut_trade_no());
                //查询不到订单数据
                if (null == dbOrder) {
                    throw new RuntimeException("订单不存在");
                }
                //充值状态：10003001待付款,10003002交易成功,10003003交易关闭,10003004交易退款，10003005交易异常
                if (!"10003001".equals(dbOrder.getRechargeStatus())) {
                    //交易成功，关闭。不处理。交易退款。
                    throw new RuntimeException("非待付款状态订单不处理");
                }
                //通过支付宝订单id手动查询订单状态
                response = AlipayUtil.queryAlipayOrderInfo(orderEntity);
                JSONObject jsonObject = JSONObject.parseObject(response).getJSONObject("alipay_trade_query_response");
                if ("10000".equals(jsonObject.get("code"))
                        && "TRADE_SUCCESS".equals(jsonObject.get("trade_status"))
                        && "Success".equals(jsonObject.get("msg"))) {
                    //2.处理金币充值
                    itUserAccountService.alterGoldCoinAmount("10000001", "10001001", dbOrder.getUserId(), dbOrder.getRechargeId(), dbOrder.getGoldCoinAmount());
                    //4.处理父级广告补贴分发
//                    arithmeticControllerCall.reward(Mode.build(dbOrder.getRechangeAmountId()));
                    //修改订单为交易成功
                    TUserAccountRechargeOrderEntity rechangeOrderEntity = new TUserAccountRechargeOrderEntity();
                    rechangeOrderEntity.setRechargeId(dbOrder.getRechargeId());
                    rechangeOrderEntity.setPayTime(new Date());
                    rechangeOrderEntity.setPaymentOrderId(orderEntity.getTrade_no());
                    String respText = dbOrder.getRespText();
                    respText += "," + response;
                    rechangeOrderEntity.setRespText(respText);
                    //5.修改订单为交易成功
                    rechangeOrderEntity.setRechargeStatus("10003002");
                    itUserAccountRechargeOrderService.updateById(rechangeOrderEntity);
                } else if ("40004".equals(jsonObject.get("code"))
                        || "TRADE_CLOSED".equals(jsonObject.get("trade_status"))) {
                    dbOrder.setPaymentOrderId(orderEntity.getTrade_no());
                    String respText = dbOrder.getRespText();
                    respText += "," + response;
                    dbOrder.setRespText(respText);
                    dbOrder.setRechargeStatus("10003003");
                    itUserAccountRechargeOrderService.updateById(dbOrder);
                    return;
                } else { //支付订单异常
                    dbOrder.setPaymentOrderId(orderEntity.getTrade_no());
                    String respText = dbOrder.getRespText();
                    respText += "," + response;
                    dbOrder.setRespText(respText);
                    dbOrder.setRechargeStatus("10003005");
                    itUserAccountRechargeOrderService.updateById(dbOrder);
                    return;
                }
            }
        } catch (Exception e) {
            try {
                RedisLockUtil.unlock(lock, lockId);
            } catch (Exception e1) {

            }
            throw e;

        }
    }

    @Override
    public void refundOrder(TUserAccountRechargeOrderEntity refundEntity) {
        TUserAccountRechargeOrderEntity entity = itUserAccountRechargeOrderService.selectById(refundEntity.getRechargeId());
        if (null == entity) {
            throw new RuntimeException("对象为空");
        }
        if (!"10003002".equals(entity.getRechargeStatus())) {
            throw new RuntimeException("非交易成功的充值订单不允许退款");
        }
        refundEntity.setRechargeStatus("10003006");//退款中
        itUserAccountRechargeOrderService.updateById(refundEntity);//更新状态
        //记录退款用户的信息进运营中心记录
        AlipayRefundEntity alipayRefundEntity = new AlipayRefundEntity();
        alipayRefundEntity.setOut_trade_no(refundEntity.getRechargeId());//订单号
        alipayRefundEntity.setRefund_reason(refundEntity.getRefundReason());//退款原因
        alipayRefundEntity.setRefund_amount(refundEntity.getRefundAmount());//退款金额
        boolean isSuccess = AlipayUtil.refund(alipayRefundEntity);
        if (!isSuccess) {
            throw new RuntimeException("退款失败！");
        }
        //退款
        refundEntity.setRechargeStatus("10003004");//交易退款
        itUserAccountRechargeOrderService.updateById(refundEntity);
        //扣除它
        itUserAccountService.alterGoldCoinAmount(
                "10000002", "10001001"
                , refundEntity.getUserId()
                , refundEntity.getRechargeId()
                , entity.getCashAmount().multiply(new BigDecimal("10")));//充值金额*10为金币金额
        //放入延时队列30秒
//        rabbitTemplate.convertAndSend(RefundAndRedPacketExchange.EXCHANGE_NAME, RefundAndRedPacketExchange.QUEUE_NAME, new MapUtils().put("type", "alipayRefund").put("refundEntity", alipayRefundEntity),
//                message -> {
//                    message.getMessageProperties().setHeader("x-delay", 3 * 1000);//3秒
//                    return message;
//                });
    }

    @Override
    public void testMq() {
        System.out.println(DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
        rabbitTemplate.convertAndSend(DemoExchange.EXCHANGE_NAME, DemoExchange.QUEUE_NAME, "123456", message -> {
            message.getMessageProperties().setHeader("x-delay", 3 * 1000);//3秒
            return message;
        });
    }
}
